package com.file.service.impl;

import com.aliyun.oss.OSSClient;
import com.file.exceptions.ExceptionEnum;
import com.file.exceptions.ServiceException;
import com.file.form.result.ImgResultForm;
import com.file.service.IOSSFileProcessService;
import com.file.utils.Const;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Random;

/**
 * 使用阿里云对象存储处理文件的访问上传下载
 * Created by chairal on 2017/7/21.
 */
@Service
public class OSSFileProcessServiceImpl implements IOSSFileProcessService {

    private final static Logger logger = LoggerFactory.getLogger(OSSFileProcessServiceImpl.class);

    @Value("${file.ossImgMapPath}")
    private String ossImgMapPath;

    @Value("${file.endPointVal}")
    private String endPointVal;

    @Value("${file.endpoint}")
    private String endpoint;

    @Value("${file.accessKeyId}")
    private String accessKeyId;

    @Value("${file.accessKeySecret}")
    private String accessKeySecret;

    @Value("${file.bucketName}")
    private String bucketName;

    String ossImagePrefixPath = "http://" + bucketName + Const.POINT + endPointVal + Const.SEPARATOR;

    /**
     * oss上传临时图片
     *
     * @param project
     * @param type
     * @param request
     * @return
     */
    public ImgResultForm uploadImageTemp(String project, String type, HttpServletRequest request){
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile file = multipartRequest.getFile("file");
        if(file.isEmpty()){
            throw new ServiceException(ExceptionEnum.EMPTY_IMAGE);
        }
        //限制图片大小
        if (file.getSize() > 2 * 1024 * 1024) {
            throw new ServiceException(ExceptionEnum.IMAGE_LIMIT_ERROR);
        }
        OSSClient client = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            //日期
            String date = DateTime.now().toString("yyyyMMdd");
            //时间
            String time = DateTime.now().toString("yyyyMMddHHmmssSSS");
            //上传文件名
            String oldFileName = file.getOriginalFilename();
            //文件扩展名
            String extension = "";
            if (StringUtils.isNotEmpty(oldFileName) && oldFileName.indexOf('.') > -1) {
                extension = oldFileName.substring(oldFileName.lastIndexOf("."));
            }
            extension = extension.toLowerCase();
            //文件夹路径
            String saveFolderPath = "";
            //项目路径
            if(StringUtils.isNotEmpty(project)){
                //文件夹路径
                saveFolderPath = Const.SEPARATOR + "temp" + Const.SEPARATOR + project;
            } else {
                //文件夹路径
                saveFolderPath = Const.SEPARATOR + "temp" + Const.SEPARATOR + "other";
            }
            //项目中的类型路径
            if(StringUtils.isNotEmpty(type)){
                //文件夹路径
                saveFolderPath = saveFolderPath + Const.SEPARATOR + type + Const.SEPARATOR + date;
            } else {
                //文件夹路径
                saveFolderPath = saveFolderPath + Const.SEPARATOR + "other" + Const.SEPARATOR + date;
            }
            //生成图片名
            String fileName = time + "_" + new Random().nextInt(1000) + extension;
            //数据库保存图片路径
            String savePath = saveFolderPath + Const.SEPARATOR + fileName;
            //判断bucket是否存在
            if (!client.doesBucketExist(bucketName)) {
                throw new ServiceException(ExceptionEnum.BUCKET_NOT_EXIST);
            }
            InputStream instream = new ByteArrayInputStream(file.getBytes());
            client.putObject(bucketName, ossImgMapPath + savePath, instream);
            String imgUrl = ossImagePrefixPath + ossImgMapPath + savePath;
            ImgResultForm imgResultForm = new ImgResultForm();
            imgResultForm.setImgUrl(imgUrl);
            return imgResultForm;
        } catch (Exception e) {
            logger.error(e.getMessage());
            throw new ServiceException(ExceptionEnum.IMAGE_UPLOAD_FAIL);
        } finally {
            if (client != null) {
                client.shutdown();
            }
        }
    }

    /**
     * oss上传图片
     *
     * @param project
     * @param type
     * @param request
     * @return
     */
    public ImgResultForm uploadImage(String project, String type, HttpServletRequest request){
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
        MultipartFile file = multipartRequest.getFile("file");
        if(file.isEmpty()){
            throw new ServiceException(ExceptionEnum.EMPTY_IMAGE);
        }
        //限制图片大小
        if (file.getSize() > 2 * 1024 * 1024) {
            throw new ServiceException(ExceptionEnum.IMAGE_LIMIT_ERROR);
        }
        OSSClient client = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            //日期
            String date = DateTime.now().toString("yyyyMMdd");
            //时间
            String time = DateTime.now().toString("yyyyMMddHHmmssSSS");
            //上传文件名
            String oldFileName = file.getOriginalFilename();
            //文件扩展名
            String extension = "";
            if (StringUtils.isNotEmpty(oldFileName) && oldFileName.indexOf('.') > -1) {
                extension = oldFileName.substring(oldFileName.lastIndexOf("."));
            }
            extension = extension.toLowerCase();
            //文件夹路径
            String saveFolderPath = "";
            //项目路径
            if(StringUtils.isNotEmpty(project)){
                //文件夹路径
                saveFolderPath = Const.SEPARATOR + project;
            } else {
                //文件夹路径
                saveFolderPath = Const.SEPARATOR + "other";
            }
            //项目中的类型路径
            if(StringUtils.isNotEmpty(type)){
                //文件夹路径
                saveFolderPath = saveFolderPath + Const.SEPARATOR + type + Const.SEPARATOR + date;
            } else {
                //文件夹路径
                saveFolderPath = saveFolderPath + Const.SEPARATOR + "other" + Const.SEPARATOR + date;
            }
            //生成图片名
            String fileName = time + "_" + new Random().nextInt(1000) + extension;
            //数据库保存图片路径
            String savePath = saveFolderPath + Const.SEPARATOR + fileName;
            //判断bucket是否存在
            if (!client.doesBucketExist(bucketName)) {
                throw new ServiceException(ExceptionEnum.BUCKET_NOT_EXIST);
            }
            InputStream instream = new ByteArrayInputStream(file.getBytes());
            client.putObject(bucketName, ossImgMapPath + savePath, instream);
            String imgUrl = ossImagePrefixPath + ossImgMapPath + savePath;
            ImgResultForm imgResultForm = new ImgResultForm();
            imgResultForm.setImgUrl(imgUrl);
            return imgResultForm;
        } catch (Exception e) {
            logger.error(e.getMessage());
            throw new ServiceException(ExceptionEnum.IMAGE_UPLOAD_FAIL);
        } finally {
            if (client != null) {
                client.shutdown();
            }
        }
    }

    /**
     * oss复制图片从临时路径到正式路径
     *
     * @param imgUrl
     * @return
     * @throws IOException
     */
    public String ossCopyFile(String imgUrl) throws IOException {
        //toonyoo-test.oss-cn-beijing.aliyuncs.com/image/temp
        String prefixUrl = ossImagePrefixPath + ossImgMapPath + Const.SEPARATOR + "temp";
        //判断图片是否是服务器临时图片
        if(imgUrl.indexOf(prefixUrl) < 0){
            throw new ServiceException(ExceptionEnum.NOT_TEMP_IMAGE);
        }
        String suffixPath = imgUrl.substring(imgUrl.lastIndexOf(prefixUrl) + prefixUrl.length());//league/contest/20170411/20170411174259_207.png
        //图片在服务器上临时路径对应的key
        String tempImgKey = ossImgMapPath + Const.SEPARATOR + "temp" + suffixPath;
        //图片在服务器上正式路径对应的key
        String imgKey = ossImgMapPath + Const.SEPARATOR + suffixPath;
        OSSClient client = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            //判断bucket是否存在
            if (!client.doesBucketExist(bucketName)) {
                throw new ServiceException(ExceptionEnum.BUCKET_NOT_EXIST);
            }
            //复制临时图片到正式路径
            client.copyObject(bucketName,tempImgKey,bucketName,imgKey);
            //删除临时图片
            client.deleteObject(bucketName, tempImgKey);
        } catch (Exception e) {
            logger.error(e.getMessage());
            throw new ServiceException(ExceptionEnum.IMAGE_UPLOAD_FAIL);
        } finally {
            if (client != null) {
                client.shutdown();
            }
        }
        return ossImagePrefixPath + imgKey;
    }

}
